package com.touka.controller;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.touka.common.Result;
import com.touka.entity.Category;
import com.touka.entity.Dish;
import com.touka.entity.Setmeal;
import com.touka.entity.SetmealDish;
import com.touka.service.CategoryService;
import com.touka.service.DishService;
import com.touka.service.SetmealDishService;
import com.touka.service.SetmealService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.context.properties.bind.DefaultValue;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 套餐管理
 */
@RestController
@RequestMapping("/setmeal")
@Slf4j
public class SetmealController {
  @Autowired
  private SetmealService setmealService;
  @Autowired
  private SetmealDishService setmealDishService;
  @Autowired
  private CategoryService categoryService;
  @Autowired
  private DishService dishService;

  /**
   * 分页查询套餐
   *
   * @param name
   * @param page
   * @param pageSize
   * @return
   */
  @GetMapping("/page")
  public Result<Map<String, Object>> list(String name, @DefaultValue("1") Long page, @DefaultValue("10") Long pageSize) {
    log.info("分页查询套餐：{}-{}-{}", name, page, pageSize);

    Page<Setmeal> pageSetmeal = new Page<>(page, pageSize);
    LambdaQueryWrapper<Setmeal> lambdaQueryWrapper = new LambdaQueryWrapper<>();
    lambdaQueryWrapper.like(StringUtils.isNotBlank(name), Setmeal::getName, name);
    Page<Setmeal> setmealPage = setmealService.page(pageSetmeal, lambdaQueryWrapper);
    setmealPage.getRecords().forEach(setmeal -> {
      Long categoryId = setmeal.getCategoryId();
      Category category = categoryService.getById(categoryId);
      if (category != null) {
        setmeal.setCategoryName(category.getName());
      }
    });

    Map<String, Object> map = new HashMap<>();
    map.put("records", setmealPage.getRecords());
    map.put("total", setmealPage.getTotal());

    return Result.success(map);
  }

  /**
   * 新增套餐
   *
   * @param setmeal
   * @return
   */
  @PostMapping
  @Transactional
  public Result<String> insert(@RequestBody Setmeal setmeal) {
    log.info("新增套餐：{}", setmeal);

    boolean save = setmealService.save(setmeal);
    if (save) {
      boolean saveBatch = setmealDishService.saveBatch(setmeal.getSetmealDishes().stream().map(setmealDish -> {
        setmealDish.setSetmealId(setmeal.getId());
        return setmealDish;
      }).toList());

      if (saveBatch) {
        return Result.success("添加成功");
      }
    }
    return Result.error("添加失败");
  }

  /**
   * 根据Id查询套餐
   *
   * @param id
   * @return
   */
  @GetMapping("/{id}")
  public Result<Setmeal> getById(@PathVariable Long id) {
    log.info("根据Id查询套餐信息：{}", id);
    Setmeal setmeal = setmealService.getById(id);
    List<SetmealDish> setmealDishes = setmealDishService.list(
            Wrappers.lambdaQuery(SetmealDish.class)
                    .eq(SetmealDish::getSetmealId, id)
    );

    setmeal.setSetmealDishes(setmealDishes);

    return Result.success(setmeal);
  }

  /**
   * 修改套餐信息
   *
   * @param setmeal
   * @return
   */
  @PutMapping
  @Transactional
  public Result<String> update(@RequestBody Setmeal setmeal) {
    log.info("修改套餐信息：{}", setmeal);

    boolean update = setmealService.updateById(setmeal);
    if (update) {
      setmealDishService.remove(
              Wrappers.lambdaQuery(SetmealDish.class)
                      .eq(SetmealDish::getSetmealId, setmeal.getId())
      );
      boolean saveBatch = setmealDishService.saveBatch(setmeal.getSetmealDishes().stream().map(setmealDish -> {
        setmealDish.setSetmealId(setmeal.getId());
        return setmealDish;
      }).toList());

      if (saveBatch) {
        return Result.success("修改成功");
      } else {
        return Result.error("修改失败");
      }
    } else {
      return Result.error("修改失败");
    }
  }

  /**
   * 停售/起售套餐
   *
   * @param status
   * @param ids
   * @return
   */
  @PostMapping("/status/{status}")
  public Result<String> status(@PathVariable Integer status, @RequestParam List<Long> ids) {
    log.info("停售/启售套餐：{}-{}", status, ids);

    boolean update = setmealService.update(
            Wrappers.lambdaUpdate(Setmeal.class)
                    .in(Setmeal::getId, ids)
                    .set(Setmeal::getStatus, status));

    return update ? Result.success("操作成功") : Result.error("操作失败");
  }

  /**
   * 删除/批量删除套餐
   *
   * @param ids
   * @return
   */
  @DeleteMapping
  @Transactional
  public Result<String> delete(@RequestParam List<Long> ids) {
    log.info("删除/批量删除套餐：{}", ids);

    boolean remove = setmealService.remove(
            Wrappers.lambdaQuery(Setmeal.class)
                    .in(Setmeal::getId, ids)
                    .eq(Setmeal::getStatus, 0)
    );
    if (remove) {
      setmealDishService.remove(Wrappers.lambdaQuery(SetmealDish.class).in(SetmealDish::getSetmealId, ids));
      return Result.success("删除成功");
    } else {
      return Result.error("删除失败,存在起售状态的套餐");
    }
  }

  /**
   * 根据分类id获取套餐
   *
   * @param categoryId
   * @param status
   * @return
   */
  @GetMapping("/list")
  public Result<List<Setmeal>> list(Long categoryId, Integer status) {
    log.info("根据分类id获取套餐：{}", categoryId);
    List<Setmeal> setmeals = setmealService.list(
            Wrappers.lambdaQuery(Setmeal.class).eq(Setmeal::getCategoryId, categoryId)
                    .eq(Setmeal::getStatus, status)
    );
    return Result.success(setmeals);
  }

  /**
   * 根据套餐id获取套餐菜品
   *
   * @param id
   * @return
   */
  @GetMapping("/dish/{id}")
  public Result<List<SetmealDish>> setmealDish(@PathVariable Long id) {
    log.info("根据套餐id获取套餐菜品：{}", id);
    List<SetmealDish> setmealDishes = setmealDishService.list(
            Wrappers.lambdaQuery(SetmealDish.class).eq(SetmealDish::getSetmealId, id)
    );
    setmealDishes.forEach(setmealDish -> {
      Dish dish = dishService.getById(setmealDish.getDishId());
      setmealDish.setImage(dish.getImage());
      setmealDish.setDescription(dish.getDescription());
    });
    return Result.success(setmealDishes);
  }
}
